package cn.tedu.mall.order.listener;

import cn.tedu.mall.common.exception.CoolSharkServiceException;
import cn.tedu.mall.common.restful.ResponseCode;
import cn.tedu.mall.front.service.IFrontSkuService;
import cn.tedu.mall.order.mappers.OrderItemMapper;
import cn.tedu.mall.order.mappers.OrderMapper;
import cn.tedu.mall.pojo.order.dto.OrderAddCondition;
import cn.tedu.mall.pojo.order.model.OmsOrder;
import cn.tedu.mall.seckill.service.ISeckillSkuService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;

import java.util.Objects;

@Component
@Slf4j
@RocketMQTransactionListener
public class TransactionOrderAddListener implements RocketMQLocalTransactionListener {

    @DubboReference
    private IFrontSkuService frontSkuService;

    @DubboReference
    private ISeckillSkuService seckillSkuService;

    @Autowired// 操作表格 oms_order
    private OrderMapper orderMapper;

    @Autowired// 操作表格 oms_order_item
    private OrderItemMapper orderItemMapper;

    @Autowired
    private OrderAddListenerRegister register;

    /**
     * 监听半消息，也就是 rocketMQTemplate.sendMessageInTransaction() 中的内容
     * 判断 增订单、删库存 是否成功 来决定是否发送半消息删除库存
     * 执行本地事务，减库存，生订单，发延迟消息
     * @param message
     * @param obj
     * @return
     */

    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object obj) {
        // 【注】转成OrderAddCondition没有问题，还是会根据不同类型（OrderAddDTO, SeckillOrderAddDTO）进入不同逻辑
        // 因为【OrderAddServiceImpl】中传入的 OrderAddCondition 已经在【OrderAddConsumer】中区分好了是普通订单还是秒杀订单的类型
        return register.execute((OrderAddCondition) obj);
    }

    /**
     * executeLocalTransaction方法返回UNKNUWN后执行的处理逻辑
     * @param message
     * @return
     */
    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
        // 为了区分是哪种订单的回调，从消息头中取得提前设置好的tag
        String tag = (String) message.getHeaders().get("tag");
        // 检查订单sn 从消息中解析sn
        String sn = (String) message.getPayload();
        // 查询到订单 return commit
        OmsOrder order = orderMapper.selectOrderBySn(sn);
        if (order != null) {
            // 再检查是否存在orderItems
            Boolean exists = orderItemMapper.selectExistsByOrderId(order.getId());
            if (exists) {
                return RocketMQLocalTransactionState.COMMIT;
            } else {
                //TODO 在有订单但是没有订单商品的时候，将订单删除
                log.debug("有订单但是没有订单商品,记录日志");
            }
        }
        // 没查到 回退库存
        if (Objects.equals(tag, "localAdd")) {
            frontSkuService.returnStock(sn);
        } else if (Objects.equals(tag, "seckillAdd")) {
            seckillSkuService.returnStock(sn);
        } else {
            throw new CoolSharkServiceException(ResponseCode.BAD_REQUEST, "不存在此类型的订单标签：" + tag);
        }
        return RocketMQLocalTransactionState.ROLLBACK;
    }
}
